#include "dragcontext.h"
#include <QDebug>
#include <QTimer>
#include <QtGlobal>
#include <algorithm>
DragContext::DragContext(QObject *parent)
    : QObject(parent)
    , m_delayedActionTimer(new QTimer(this))
{
    m_delayedActionTimer->setSingleShot(true);
    connect(m_delayedActionTimer, &QTimer::timeout, this, &DragContext::executeDelayedAction);
}
DragContext::~DragContext()
{
    cancelDelayedActions();
}
void DragContext::startDrag(const QList<int>& sourceIndices)
{
    if (m_isDragInProgress) {
        return;
    }
    m_isDragInProgress = true;
    m_sourceIndices = sourceIndices;
    m_targetIndex = -1;
    m_newPositions.clear();
    emit dragStarted(m_sourceIndices);
}
void DragContext::setTargetIndex(int targetIndex)
{
    if (!m_isDragInProgress) {
        return;
    }
    m_targetIndex = targetIndex;
}
void DragContext::calculateNewPositions(int fileCount)
{
    if (!m_isDragInProgress || m_targetIndex < 0) {
        return;
    }
    m_newPositions.clear();
    // 计算被拖拽文件的新位置
    // 如果目标索引大于等于文件总数，意味着要移动到末尾
    int actualTargetIndex;
    if (m_targetIndex >= fileCount) {
        // 拖拽到末尾：新位置从 (fileCount - 源文件数量) 开始
        actualTargetIndex = fileCount - m_sourceIndices.size();
    } else {
        actualTargetIndex = m_targetIndex;
    }
    // 检查源索引是否已经按顺序排序，如果不是则排序
    QList<int> sortedSourceIndices = m_sourceIndices;
    std::sort(sortedSourceIndices.begin(), sortedSourceIndices.end());
    // 根据目标位置和源索引的相对关系计算新位置
    for (int i = 0; i < sortedSourceIndices.size(); ++i) {
        int newPos = actualTargetIndex + i;
        // 确保新位置在有效范围内
        if (newPos >= 0 && newPos < fileCount) {
            m_newPositions.append(newPos);
        } else {
        }
    }
}
void DragContext::completeDrag()
{
    if (!m_isDragInProgress) {
        return;
    }
    emit dragCompleted(m_newPositions);
    // 重置状态
    m_isDragInProgress = false;
    m_sourceIndices.clear();
    m_targetIndex = -1;
    m_newPositions.clear();
}
void DragContext::cancelDrag()
{
    if (!m_isDragInProgress) {
        return;
    }
    emit dragCancelled();
    // 重置状态
    m_isDragInProgress = false;
    m_sourceIndices.clear();
    m_targetIndex = -1;
    m_newPositions.clear();
}
void DragContext::scheduleDelayedAction(std::function<void()> action, int delayMs)
{
    if (m_hasDelayedAction) {
        cancelDelayedActions();
    }
    m_delayedAction = action;
    m_hasDelayedAction = true;
    m_delayedActionTimer->start(delayMs);
}
void DragContext::cancelDelayedActions()
{
    if (m_hasDelayedAction) {
        m_delayedActionTimer->stop();
        m_delayedAction = nullptr;
        m_hasDelayedAction = false;
    }
}
void DragContext::executeDelayedAction()
{
    if (m_hasDelayedAction && m_delayedAction) {
        m_delayedAction();
        m_delayedAction = nullptr;
        m_hasDelayedAction = false;
    }
}
